﻿namespace Pyramid.Hardware
{
    public class ManualClock
    {
        private ClockState state;
        private readonly OutputLine output;

        public ManualClock()
        {
            state = ClockState.Trough;
            output = new OutputLine(Trivalent.False);
        }

        public void Cycle()
        {
            for (int tickIndex = 0; tickIndex < 4; tickIndex++)
            {
                this.Tick();
            }
        }

        public void Tick()
        {
            switch (state)
            {
                case ClockState.Trough:
                    state = ClockState.RisingEdge;
                    output.SetOutput(Trivalent.Unknown);
                    break;
                case ClockState.RisingEdge:
                    state = ClockState.Peak;
                    output.SetOutput(Trivalent.True);
                    break;
                case ClockState.Peak:
                    state = ClockState.FallingEdge;
                    output.SetOutput(Trivalent.Unknown);
                    break;
                case ClockState.FallingEdge:
                default: //Unknown state - revert to initial state
                    state = ClockState.Trough;
                    output.SetOutput(Trivalent.False);
                    break;
            }
        }

        public ILine Output
        {
            get
            {
                return output;
            }
        }

        private enum ClockState
        {
            Trough,
            RisingEdge,
            Peak,
            FallingEdge
        }
    }
}